package com.yvan.leto.server.controller;

import com.yvan.leto.server.domain.UserAgent;
import com.yvan.leto.server.security.JwtHelper;
import com.yvan.leto.server.service.UserService;
import com.yvan.leto.server.utils.HttpUtil;
import com.yvan.platform.ResultModel;
import com.yvan.platform.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.Cookie;

@RestController
@Slf4j
public class LoginController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/login.htm")
    public ModelAndView loginHtm() {
        return new ModelAndView("/user/login.ftl");
    }

    @GetMapping("/user/logout.htm")
    public ModelAndView logout() {
        HttpUtil.removeCookie(JwtHelper.AUTH_COOKIE_NAME, "/");
        SecurityUtils.getSubject().logout();
        return new ModelAndView(new RedirectView("/"));
    }

    @PostMapping("/user/signup.json")
    public Object signUpPost(@RequestParam("signup_name") String signupName,
                             @RequestParam("signup_pwd") String signupPwd) {

        if (StringUtils.isNullOrEmpty(signupName) || signupName.length() < 5 || signupName.length() > 50) {
            return ResultModel.newFail("用户名不能大于50个字，不能小于5个字");
        }

        ResultModel model;
        try {
            UserAgent userAgent = userService.createUser(signupName, signupPwd);

            String jwt = userService.createJwt(userAgent, false);

            HttpUtil.currentResponse().addHeader(JwtHelper.AUTH_HEADER_NAME, jwt);
            Cookie cookie = new Cookie(JwtHelper.AUTH_COOKIE_NAME, jwt);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            HttpUtil.writeCookie(cookie);
            model = ResultModel.newSuccess().set("href", "/");

        } catch (Exception e) {
            model = processException(e);
        }
        return model;
    }

    @PostMapping("/user/signin.json")
    public Object loginPost(@RequestParam("login_name") String loginName,
                            @RequestParam("login_password") String loginPassword,
                            @RequestParam("remember_me") boolean rememberMe) {

        UserAgent userAgent;
        ResultModel model;
        try {
            userAgent = userService.getAgentByPassword(loginName);
            if (userAgent == null) {
                throw new UnknownAccountException();
            }
            String secretPwd = userService.createPassword(userAgent, loginPassword);

            //校验密码
            if (!secretPwd.equals(userAgent.getLoginPassword())) {
                throw new IncorrectCredentialsException();
            }

            String jwt = userService.createJwt(userAgent, rememberMe);
            HttpUtil.currentResponse().addHeader(JwtHelper.AUTH_HEADER_NAME, jwt);

            Cookie cookie = new Cookie(JwtHelper.AUTH_COOKIE_NAME, jwt);
            cookie.setPath("/");
            cookie.setHttpOnly(true);
            if (rememberMe) {
                //如果用户要求记住登录状态
                Long seconds = new Duration(DateTime.now(), JwtHelper.getExpireTime(jwt)).getStandardSeconds();
                cookie.setMaxAge(seconds.intValue());
            }
            HttpUtil.writeCookie(cookie);
            model = ResultModel.newSuccess().set("href", "/");

        } catch (Exception e) {
            model = processException(e);
        }

        return model;
    }

    private ResultModel processException(Exception e) {
        if (e instanceof ConcurrentAccessException) {
            return ResultModel.newFail("用户名已经存在");
        }
        if (e instanceof UnknownAccountException) {
            return ResultModel.newFail("登录账号不存在!");
        }
        if (e instanceof LockedAccountException) {
            return ResultModel.newFail("用户已经被锁定不能登录，请与管理员联系！");
        }
        if (e instanceof DisabledAccountException) {
            return ResultModel.newFail("用户已经被禁用，请与管理员联系！");
        }
        if (e instanceof ExcessiveAttemptsException) {
            return ResultModel.newFail("登录失败次数过多！");
        }
        if (e instanceof ExpiredCredentialsException) {
            return ResultModel.newFail("凭证过期！");
        }
        if (e instanceof IncorrectCredentialsException) {
            return ResultModel.newFail("密码错误!");
        }
        if (e instanceof AuthenticationException) {
            return ResultModel.newFail("用户或密码不正确！");
        }

        log.error("e", e);
        return ResultModel.newFail("未知错误:" + e.getMessage());
    }
}
